package com.zlzlib.libscan;

import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


/**
 * Created by zlz on 2018/9/12.
 * 照相显示的页面
 */
public class ScanCameraView extends SurfaceView implements SurfaceHolder.Callback,
        GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, ScaleGestureDetector.OnScaleGestureListener {
    //自动对焦成功后，再次对焦的延迟
    private long autoFocusSuccessDelay = 1000L;
    //自动对焦失败后，再次对焦的延迟
    private long autoFocusFailureDelay = 500L;
    private boolean surfaceCreated = false;
    //是否正在获取照相数据
    private boolean previewing = true;
    private Camera mCamera;
    private CameraConfigManager cameraManager;
    //手势
    private GestureDetector gestureDetector;
    private ScaleGestureDetector scaleGestureDetector;
    private boolean isZoom = false;
    private FocusSuccessListener focusListener;

    public ScanCameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        gestureDetector = new GestureDetector(context,this);
        gestureDetector.setOnDoubleTapListener(this);
        scaleGestureDetector = new ScaleGestureDetector(context, this);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        gestureDetector.onTouchEvent(event);
        scaleGestureDetector.onTouchEvent(event);
        return true;
    }

    public void setCamera(Camera camera, FocusSuccessListener listener) {
        mCamera = camera;
        focusListener = listener;
        if (mCamera != null) {
            cameraManager = new CameraConfigManager(getContext());
            cameraManager.initCameraParameters(mCamera);
            getHolder().addCallback(this);
            if (previewing) {
                requestLayout();
            } else {
                showCameraPreview();
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //创建开始
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (holder.getSurface() == null) {
            return;
        }
        surfaceCreated = true;
        stopCameraPreview();
        showCameraPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        surfaceCreated = false;
        stopCameraPreview();
    }

    private void showCameraPreview() {
        post(new Runnable() {
            @Override
            public void run() {
                if (mCamera != null) {
                    try {
                        previewing = true;
                        mCamera.setPreviewDisplay(getHolder());
                        cameraManager.setBestCameraParameters(mCamera);
                        mCamera.startPreview();
                        mCamera.autoFocus(autoFocusCB);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    protected void stopCameraPreview() {
        if (mCamera != null) {
            try {
                removeCallbacks(doAutoFocus);
                previewing = false;
                mCamera.cancelAutoFocus();
                mCamera.setOneShotPreviewCallback(null);
                mCamera.stopPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    protected void openFlashlight() {
        if (flashLightAvailable()) {
            cameraManager.openFlashlight(mCamera);
        }
    }

    protected void closeFlashlight() {
        if (flashLightAvailable()) {
            cameraManager.closeFlashlight(mCamera);
        }
    }

    private boolean flashLightAvailable() {
        return cameraManager != null && previewing && surfaceCreated &&
                getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //设置当前控件的大小
        int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        if (cameraManager != null && cameraManager.getCameraResolution() != null) {
            Point cameraResolution = cameraManager.getCameraResolution();
            // 取出来的cameraResolution高宽值与屏幕的高宽顺序是相反的
            int cameraPreviewWidth = cameraResolution.x;
            int cameraPreviewHeight = cameraResolution.y;
            if (width * 1f / height < cameraPreviewWidth * 1f / cameraPreviewHeight) {
                float ratio = cameraPreviewHeight * 1f / cameraPreviewWidth;
                width = (int) (height / ratio + 0.5f);
            } else {
                float ratio = cameraPreviewWidth * 1f / cameraPreviewHeight;
                height = (int) (width / ratio + 0.5f);
            }
        }
        //设置 精确模式（MeasureSpec.EXACTLY）
        super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
    }

    //设置自动对焦
    private Runnable doAutoFocus = new Runnable() {
        public void run() {
            //判断相机是否存在  是否开始拍照  是否创建surface
            if (mCamera != null && previewing && surfaceCreated) {
                try {
                    mCamera.autoFocus(autoFocusCB);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };

    //相机自动对焦的回调
    private Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
            if (success) {
                //对焦成功
                if (null != focusListener) focusListener.success();
                postDelayed(doAutoFocus, autoFocusSuccessDelay);
            } else {
                postDelayed(doAutoFocus, autoFocusFailureDelay);
            }
        }
    };

    public long getAutoFocusSuccessDelay() {
        return autoFocusSuccessDelay;
    }

    public void setAutoFocusSuccessDelay(long autoFocusSuccessDelay) {
        this.autoFocusSuccessDelay = autoFocusSuccessDelay;
    }

    public long getAutoFocusFailureDelay() {
        return autoFocusFailureDelay;
    }

    public void setAutoFocusFailureDelay(long autoFocusFailureDelay) {
        this.autoFocusFailureDelay = autoFocusFailureDelay;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return false;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        if (null != mCamera) {
            //双击    缩放照相大小
            if (isZoom) {
                isZoom = false;
                //还原
                cameraManager.setZoom(mCamera, 0);
            } else {
                isZoom = true;
                //放大
                cameraManager.setZoom(mCamera, cameraManager.TEN_DESIRED_ZOOM);
            }
        }
        return false;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        if (null != mCamera) {
            //设置缩放  计算放大或者缩小的倍数
            int scale = (int) (50 * (detector.getScaleFactor() - 1f));
            if (scale > 12) {
                scale = 12;
            }
            cameraManager.setZoom(mCamera, cameraManager.zoom_now + scale);
        }
        return false;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
    }

    public interface FocusSuccessListener {
        void success();
    }
}
